home *** CD-ROM | disk | FTP | other *** search
- /* ------------------------------------ */
- /* -- Logical Answers Byte -- */
- /* -- Our Real Good Memory Manager -- */
- /* ------------------------------------ */
-
- #include <alloc.h>
- #include <stdlib.h>
- #include <stdio.h>
-
- #define LATRACE 1 /* Compile with LATRACE enabled */
- /* To disable LATRACE, Comment this statement */
-
- #include <LAByte.h>
-
- void *MemAnchor = NULL; /* First storage chain pointer */
- TRACETBL *TraceTbl = NULL; /* Function trace table */
-
- char far *mem_getmain(char *Mod, int Line, char Funct, char Use, int Len)
- {
- char far *Area, *Work;
- unsigned long C, W;
- MEMTBL *MemBlock, *MemWork;
-
- trace_entry('E', "Mem", __LINE__); /* Trace Entry to Paragraph */
-
- C = farcoreleft();
- W = Len + 9;
- if (!(W < C))
- return(NULL);
- Area = farmalloc(W);
- memset(Area, NULL, W);
- memcpy(Area, "^MH^", MEMHDRLEN);
- Work = Area + Len + MEMHDRLEN;
- memcpy(Work, "^MT^", MEMHDRLEN);
- Area = Area + MEMHDRLEN;
- MemBlock = malloc(sizeof(MEMTBL));
- MemBlock->MemOK = 0;
- strcpy(MemBlock->MemMod, Mod);
- MemBlock->MemLine = Line;
- MemBlock->MemFun = Funct;
- MemBlock->MemUse = Use;
- MemBlock->MemLen = Len;
- MemBlock->MemAddr = Area;
- MemBlock->MemNext = MemAnchor;
- MemBlock->MemPrev = NULL;
- MemWork = MemAnchor;
- MemWork->MemPrev = MemBlock;
- MemAnchor = MemBlock;
- return(Area);
- }
-
- int mem_freemain(char *Mod, int Line, char far *Area)
- {
- char far *Work;
- MEMTBL *MemBlock, *MemWork;
-
- trace_entry('E', "Mem", __LINE__); /* Trace Entry to Paragraph */
-
- MemBlock = MemAnchor;
- if (MemBlock == NULL)
- {
- mem_cancel(Line, Mod, 1, MemBlock, Area);
- return(-2);
- }
- for(;;)
- {
- if (MemBlock->MemAddr == Area)
- break;
- if (MemBlock->MemNext == NULL)
- {
- mem_cancel(Line, Mod, 2, MemBlock, Area);
- return(-2);
- }
- MemBlock = MemBlock->MemNext;
- }
- MemWork = MemBlock->MemNext;
- if (MemWork != NULL)
- {
- if (MemWork->MemPrev != MemBlock)
- {
- mem_cancel(Line, Mod, 3, MemWork, Area);
- return(-2);
- }
- }
- MemWork = MemBlock->MemPrev;
- if (MemWork != NULL)
- {
- if (MemWork->MemNext != MemBlock)
- {
- mem_cancel(Line, Mod, 4, MemWork, Area);
- return(-2);
- }
- }
- Work = MemBlock->MemAddr;
- Work = Work - MEMHDRLEN;
- if (memcmp(Work, "^MH^", MEMHDRLEN) != 0)
- {
- mem_cancel(Line, Mod, 5, MemBlock, Area);
- return(2);
- }
- Work = MemBlock->MemAddr;
- Work = Work + MemBlock->MemLen;
- if (memcmp(Work, "^MT^", MEMHDRLEN) != 0)
- {
- mem_cancel(Line, Mod, 6, MemBlock, Area);
- return(-2);
- }
- MemWork = MemBlock->MemNext;
- if (MemWork != NULL)
- MemWork->MemPrev = MemBlock->MemPrev;
- MemWork = MemBlock->MemPrev;
- if (MemWork != NULL)
- MemWork->MemNext = MemBlock->MemNext;
- else
- MemAnchor = MemBlock->MemNext;
- Area = MemBlock->MemAddr;
- Area = Area - MEMHDRLEN;
- farfree(Area);
- free(MemBlock);
- return(0);
- }
-
- int mem_cleanup(char *Mod, int Line, char Funct)
- {
- char *Area;
- int Ret;
- MEMTBL *MemBlock, *MemWork, *Next, *Prev;
-
- trace_entry('E', "Mem", __LINE__); /* Trace Entry to Paragraph */
-
- Ret = mem_scan();
- if (Ret)
- {
- mem_cancel(Line, Mod, 10+Ret, MemBlock, NULL);
- return(-2);
- }
-
- MemBlock = MemAnchor;
- for(;;)
- {
- Next = MemBlock->MemNext;
- Prev = MemBlock->MemPrev;
- if (MemBlock->MemFun == Funct)
- {
- if (Next != NULL)
- Next->MemPrev = Prev;
- if (Prev != NULL)
- Prev->MemNext = Next;
- else
- MemAnchor = Next;
- Area = MemBlock->MemAddr;
- Area = Area - MEMHDRLEN;
- farfree(Area);
- free(MemBlock);
- MemBlock = Next;
- }
- if (Next == NULL)
- break;
- MemBlock = Next;
- }
- return(0);
- }
-
- int mem_freeall(char *Mod, int Line)
- {
- char far *Area;
- int Ret;
- MEMTBL *MemBlock, *MemWork;
-
- trace_entry('E', "Mem", __LINE__); /* Trace Entry to Paragraph */
-
- Ret = mem_scan();
- if (Ret)
- {
- mem_cancel(Line, Mod, 20+Ret, MemBlock, NULL);
- return(-2);
- }
- MemBlock = MemAnchor;
- for(;;)
- {
- Area = MemBlock->MemAddr;
- Area = Area - MEMHDRLEN;
- farfree(Area);
- MemWork = MemBlock->MemNext;
- free(MemBlock);
- if (MemWork == NULL)
- break;
- MemBlock = MemWork;
- }
- MemAnchor = NULL;
- return(0);
- }
-
- int mem_scan()
- {
- char far *Work;
- MEMTBL *MemBlock, *MemWork;
-
- trace_entry('E', "Mem", __LINE__); /* Trace Entry to Paragraph */
-
- MemBlock = MemAnchor;
- for(;;)
- {
- if (MemBlock == NULL)
- break;
- MemWork = MemBlock->MemNext;
- if (MemWork != NULL)
- {
- if (MemWork->MemPrev != MemBlock)
- {
- return(1);
- }
- }
- Work = MemBlock->MemAddr;
- Work = Work - MEMHDRLEN;
- if (memcmp(Work, "^MH^", MEMHDRLEN) != 0)
- {
- return(2);
- }
- Work = MemBlock->MemAddr;
- Work = Work + MemBlock->MemLen;
- if (memcmp(Work, "^MT^", MEMHDRLEN) != 0)
- {
- return(3);
- }
- MemBlock = MemBlock->MemNext;
- }
- return(0);
- }
-
- void mem_cancel(int Line, char *Mod, int Code, void far *Memory, char far *Area)
- {
- MEMTBL *MemBlock;
-
- MemBlock = Memory;
- MemBlock->MemOK = Code;
- puts("\n\n\n\n");
- puts(" [ -- ERROR -- ]\n\n");
- puts(" A memory error has occurred as a result of a request");
- printf(" from line %d of module %s. The error code was %d",
- Line, Mod, Code);
- if (Area != NULL)
- printf(" The pointer to the area is %p\n", Area);
- puts("\n\n\n\n");
- cancel_prog(4);
- }
-
-
-
- /* ------------------------- */
- /* LATrace Logic */
- /* ------------------------- */
-
- void trace_entry(char Type, char *Mod, int Line)
- {
- int I;
-
- #ifdef LATRACE
- if (TraceTbl == NULL)
- {
- TraceTbl = malloc((TRACEELEMS * sizeof(TraceTbl->TraceElem[0])) + 8);
- TraceTbl->Wrap = 'N';
- TraceTbl->TracePtr = 0;
- }
- I = TraceTbl->TracePtr;
- TraceTbl->TraceElem[I].Type = Type;
- strcpy(TraceTbl->TraceElem[I].Mod, Mod);
- TraceTbl->TraceElem[I].Line = Line;
- ++TraceTbl->TracePtr;
- if (TraceTbl->TracePtr > 99)
- {
- TraceTbl->Wrap = 'Y';
- TraceTbl->TracePtr = 0;
- }
- #endif
- return;
- }
-
-
- /* Dump the trace and memory information to a file names "LATrace.Lac" */
- /* and end the program with the specified exit code. */
-
- void cancel_prog(int ExitCode)
- {
- int Start, Curr;
- FILE *TraceFile;
- MEMTBL *MemBlock, *MemWork;
-
- TraceFile = fopen("LATrace.Lac", "w");
- if (TraceFile == NULL)
- exit(ExitCode);
-
- #ifdef LATRACE
- fputs("----- Trace Table -----\n", TraceFile);
- if (TraceTbl->Wrap == 'N')
- Start = 0;
- else
- Start = TraceTbl->TracePtr;
- Curr = Start;
- for(;;)
- {
- fprintf(TraceFile, "T---%c---%s---%d\n",
- TraceTbl->TraceElem[Curr].Type,
- TraceTbl->TraceElem[Curr].Mod,
- TraceTbl->TraceElem[Curr].Line);
- ++Curr;
- if (Curr == TraceTbl->TracePtr)
- break;
- if (Curr > 99)
- Curr = 0;
- }
- #endif
-
- fputs("----- Storage -----\n", TraceFile);
- MemBlock = MemAnchor;
- if (MemAnchor == NULL)
- fputs(" No Storage On Chain\n", TraceFile);
- else
- {
- for(;;)
- {
- fprintf(TraceFile,
- "M---%p---%d---%s---%d---%c---%c---%d---%p---%p---%p\n",
- MemBlock,
- MemBlock->MemOK,
- MemBlock->MemMod,
- MemBlock->MemLine,
- MemBlock->MemFun,
- MemBlock->MemUse,
- MemBlock->MemLen,
- MemBlock->MemAddr,
- MemBlock->MemPrev,
- MemBlock->MemNext);
- MemWork = MemBlock->MemNext;
- if (MemWork == NULL)
- break;
- MemBlock = MemWork;
- }
- }
-
- fclose(TraceFile);
- exit(ExitCode);
- }
-